#include "VSTexAllState.h"
#include "VS2DTexture.h"
#include "VSResourceManager.h"
#include "VSImage.h"
#include "VSGraphicInclude.h"
#include "VSStream.h"
using namespace VSEngine2;
IMPLEMENT_RTTI(VSTexAllState,VSObject)
VSPointer<VSTexAllState> VSTexAllState::Default;
VSPointer<VSTexAllState> VSTexAllState::ms_pOrenNayarLookUpTable;
bool VSTexAllState::ms_bIsEnableASYNLoader = true;
bool VSTexAllState::ms_bIsEnableGC = true;
BEGIN_ADD_PROPERTY(VSTexAllState,VSObject)
REGISTER_PROPERTY(m_ResourceName,ResourceName,VSProperty::F_SAVE_LOAD_CLONE)
REGISTER_PROPERTY(m_pTex,Tex,VSProperty::F_SAVE_LOAD_CLONE)
REGISTER_PROPERTY(m_SamplerDesc,SamplerDesc,VSProperty::F_SAVE_LOAD_CLONE)
END_ADD_PROPERTY
IMPLEMENT_INITIAL_BEGIN(VSTexAllState)
ADD_PRIORITY(VS2DTexture)
ADD_PRIORITY(VSSamplerState)
ADD_INITIAL_FUNCTION_WITH_PRIORITY(InitialDefaultState)
ADD_TERMINAL_FUNCTION(TerminalDefaultState)
IMPLEMENT_INITIAL_END
bool VSTexAllState::InitialDefaultState()
{
	VSFileName FileName = VSResourceManager::ms_TexturePath + _T("Default.bmp");
	Default = VSResourceManager::Load2DTexture(FileName.GetBuffer());
	if(!Default)
		return 0;

	//
	
	unsigned int uiOrenNayarTexSize = 128;
	unsigned short * pBuffer = VS_NEW unsigned short[uiOrenNayarTexSize * uiOrenNayarTexSize];
	for (unsigned int i = 0 ; i < uiOrenNayarTexSize ;i++)
	{
		float VdotN = (i * 1.0f / (uiOrenNayarTexSize - 1)) * 2.0f - 1.0f;
		float AngleViewNormal = ACOS(VdotN);
		for (unsigned int j = 0 ; j < uiOrenNayarTexSize ; j++)
		{			
			float LdotN = (j * 1.0f / (uiOrenNayarTexSize - 1)) * 2.0f - 1.0f;
			float AngleLightNormal = ACOS(LdotN);
			
			float Alpha = Max(AngleViewNormal,AngleLightNormal);
			float Beta = Min(AngleViewNormal,AngleLightNormal);
			float fResult = ABS(SIN(Alpha) * TAN(Beta));
			pBuffer[i * uiOrenNayarTexSize + j] = FloatToHalf(fResult);	
		}
	}
	ms_pOrenNayarLookUpTable = VSResourceManager::Create2DTexture(uiOrenNayarTexSize,uiOrenNayarTexSize,VSRenderer::SFT_R16F,1,pBuffer);
	VSMAC_DELETEA(pBuffer);

	VSSamplerDesc SamplerDesc;
	SamplerDesc.m_uiMag = VSSamplerDesc::FM_LINE;
	SamplerDesc.m_uiMin = VSSamplerDesc::FM_LINE;
	SamplerDesc.m_uiMip = VSSamplerDesc::FM_LINE;
	VSSamplerStatePtr pSamplerState = VSResourceManager::CreateSamplerState(SamplerDesc);
	ms_pOrenNayarLookUpTable->SetSamplerState(pSamplerState);
	if (!ms_pOrenNayarLookUpTable)
	{
		return false;
	}

	return 1;
}
bool VSTexAllState::TerminalDefaultState()
{
	Default = NULL;
	ms_pOrenNayarLookUpTable = NULL;
	return 1;
}
VSTexAllState::VSTexAllState(VSTexture * pTexture)
{
	m_pTex = pTexture;
	m_pSamplerState = (VSSamplerState *)VSSamplerState::GetDefault();
}
VSTexAllState::VSTexAllState()
{
	m_pTex			= NULL;
	m_pSamplerState = NULL;
}
VSTexAllState::~VSTexAllState()
{
	m_pTex			= NULL;

	m_pSamplerState = NULL;
}
bool VSTexAllState::PostLoad(void * pDate)
{
	m_pSamplerState = VSResourceManager::CreateSamplerState(m_SamplerDesc);
	return true;
}
unsigned int VSTexAllState::DiskUse()const
{
	unsigned int Use = VSObject::DiskUse();
	Use += VSResource::DiskUse();
	Use += m_SamplerDesc.DiskUse();
	Use += sizeof(VSTexture *);

	return Use;
}
bool VSTexAllState::Save(VSStream & rStream,unsigned int &iSaveUse)const
{
	if(!VSObject::Save(rStream,iSaveUse))
		return false;
	if (!VSResource::Save(rStream,iSaveUse))
	{
		return false;
	}
	VSTexture * pTex = m_pTex;
	if(!pTex)
		return 0;
// 	if(!rStream.Write(&pTex,sizeof(VSTexture *)))
// 		return 0;
	if(!rStream.WriteObjectPtr(m_pTex))
		return 0;
	iSaveUse += sizeof(VSTexture *);

	
	if (!m_SamplerDesc.Save(rStream,iSaveUse))
	{
		return 0;
	}
	return 1;
}
bool VSTexAllState::Load(VSStream & rStream,unsigned int &iSaveUse)
{

	if(!VSObject::Load(rStream,iSaveUse))
		return false;

	if (!VSResource::Load(rStream,iSaveUse))
	{
		return false;
	}
// 	VSTexture * pTex = NULL;
// 	if(!rStream.Read(&pTex,sizeof(VSTexture *)))
// 		return 0;
// 	AddLink(pTex);
	if(!rStream.ReadObjectPtr(m_pTex))
		return 0;
	iSaveUse += sizeof(VSTexture *);

	if(!m_SamplerDesc.Load(rStream,iSaveUse))
		return 0;

	return 1;
}
bool VSTexAllState::Clone(const VSObject *pObject,unsigned int uiType)
{
	const VSTexAllState* Temp = DynamicCast<VSTexAllState>(pObject); 
	if(!Temp)
		return 0;
	if(!Temp->m_pTex)
		return 0;

	if(VSObject::Clone(pObject,uiType) && VSResource::Clone(Temp,uiType))
	{
		if(Temp->m_pTex)
		{
			VSTexture * pTemp1  = Temp->m_pTex;
			VSTexture * pTemp2 =(VSTexture *)VSObject::GetInstance( (pTemp1)->GetType().GetName() );
			pTemp2->Clone(pTemp1,uiType);
			m_pTex = pTemp2;
		}
		else
		{
			m_pTex = NULL;
		}
		m_pSamplerState = Temp->m_pSamplerState;
	
		m_SamplerDesc = Temp->m_SamplerDesc;
		return 1;
	}
	else
	{
		return 0;

	}
}
bool VSTexAllState::Link(VSStream & rStream)
{
	if(!VSObject::Link(rStream))
		return 0;

	

	rStream.LinkObjectPtr(m_pTex);
	

	return 1;
}
bool VSTexAllState::Register(VSStream & rStream)const
{
	if (rStream.IsObjectRegister(this))
	{
		return 1;
	}
	if(!VSObject::Register(rStream))
		return 0;

	if(m_pTex)
	{
		if(!m_pTex->Register(rStream))
			return 0;
	}
	else
		return 0;




	return 1;
}

